/**
 * Copyright (c) 2019 xstgongyi.org
 * All rights reserved.
 */
package org.xstgongyi.eduaid.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.xstgongyi.eduaid.common.ControllerHelper;
import org.xstgongyi.eduaid.dataobject.StudentBankAccountDO;
import org.xstgongyi.eduaid.dataobject.StudentDO;
import org.xstgongyi.eduaid.dataobject.GradeDO;
import org.xstgongyi.eduaid.dataobject.ProjectDO;
import org.xstgongyi.eduaid.dataobject.SemesterDO;
import org.xstgongyi.eduaid.service.GradeService;
import org.xstgongyi.eduaid.service.ProjectService;
import org.xstgongyi.eduaid.service.SemesterService;
import org.xstgongyi.eduaid.service.StudentService;

/**
 * @author oldcrane<br/>
 * @created 2019-04-11
 */
@Controller
@RequestMapping("/students")
public class StudentController {

	@Autowired
	private StudentService studentService;

	@Autowired
	private ProjectService projectService;

	@Autowired
	private SemesterService semesterService;

	@Autowired
	private GradeService gradeService;

	@GetMapping("/entry")
	public String entryPage(ModelMap map) {
		return "aid/student_list";
	}

	@GetMapping("")
	@ResponseBody
	public Map<String, Object> list(@RequestParam(name = "projectId", defaultValue = "0") int projectId,
			@RequestParam(name = "status", defaultValue = "") String status,
			@RequestParam(name = "keyword", defaultValue = "") String keyword,
			@RequestParam(name = "page", defaultValue = "1") int pageNumber,
			@RequestParam(name = "limit", defaultValue = "20") int pageSize) {

		Map<String, Object> result = new HashMap<>();
		List<StudentVO> rows = new ArrayList<>();

		int total = studentService.countTotal(projectId, status, keyword);
		if (total > 0) {
			List<StudentDO> students = studentService.listPage(pageNumber, pageSize, projectId, status, keyword);
			// translate from DO to VO
			for (StudentDO item : students) {
				StudentVO vo = StudentVO.of(item);
				ProjectDO project = projectService.getById(item.getProjectId());
				vo.setProjectName(null == project ? null : project.getName());
				SemesterDO semester = semesterService.getById(item.getRegSemesterId());
				vo.setRegSemesterName(null == semester ? null : semester.getName());
				if (null != item.getRegGradeId()) {
					GradeDO grade = gradeService.getById(item.getRegGradeId());
					vo.setRegGradeName(null == grade ? null : grade.getName());
				}
				rows.add(vo);
			}
		}
		result.put("page", pageNumber);
		result.put("total", total);
		result.put("rows", rows);
		return ControllerHelper.successResponse(result);
	}

	@PostMapping("")
	@ResponseBody
	public Map<String, Object> addStudent(@RequestBody StudentVO vo) {
		// translate VO to DO
		StudentDO student = vo.toDO();
		studentService.insertStudent(student);

		if (null != vo.getBankAccountName() && null != vo.getBankAccountNumber() && null != vo.getBankAccountRelation()
				&& null != vo.getBankName()) {
			// 银行账户信息的四个字段都必须有值才能保存
			StudentBankAccountDO bankAccount = new StudentBankAccountDO();
			bankAccount.setName(vo.getBankAccountName());
			bankAccount.setNumber(vo.getBankAccountNumber());
			bankAccount.setRelation(vo.getBankAccountRelation());
			bankAccount.setBank(vo.getBankName());
			bankAccount.setStudentId(student.getId());
			studentService.insertBankAccount(bankAccount);
		}

		return ControllerHelper.successResponse(null);
	}

	@GetMapping("/{id}")
	@ResponseBody
	public Map<String, Object> getStudent(@PathVariable("id") Integer id) {
		StudentDO student = studentService.getStudentById(id);
		if (null == student) {
			return ControllerHelper.errorResponse(404, "studnet(id=" + id + ") not exist.");
		}

		// translate from DO to VO
		StudentVO vo = StudentVO.of(student);
		ProjectDO project = projectService.getById(student.getProjectId());
		vo.setProjectName(null == project ? null : project.getName());
		SemesterDO semester = semesterService.getById(student.getRegSemesterId());
		vo.setRegSemesterName(null == semester ? null : semester.getName());
		if (null != student.getRegGradeId()) {
			GradeDO grade = gradeService.getById(student.getRegGradeId());
			vo.setRegGradeName(null == grade ? null : grade.getName());
		}

		if (null != student.getBankAccountId()) {
			StudentBankAccountDO bankAccount = studentService.getBankAccountById(student.getBankAccountId());
			if (null != bankAccount) {
				vo.setBankAccountName(bankAccount.getName());
				vo.setBankAccountNumber(bankAccount.getNumber());
				vo.setBankAccountRelation(bankAccount.getRelation());
				vo.setBankName(bankAccount.getBank());
			}
		}

		return ControllerHelper.successResponse(vo);
	}

	@PostMapping("/{id}")
	@ResponseBody
	public Map<String, Object> updateStudent(@PathVariable("id") Integer studentId, @RequestBody StudentVO vo) {
		// 调用者可能只提供部分字段信息，需要先从数据库load记录，以补全属性。
		// 部分字段不可通过此接口修改，详见 StudentVO.mergeToDo()方法
		//StudentDO student = studentService.getStudentById(studentId);
		//student = vo.mergeToDo(student);
		StudentDO student = vo.toDO();
		student.setId(studentId);
		studentService.updateStudent(student);
		return ControllerHelper.successResponse(null);
	}

	@PostMapping("/{id}/attribute")
	@ResponseBody
	public Map<String, Object> updateStudentAttribute(@PathVariable("id") Integer studentId,
			@RequestBody Map<String, String> vo) {
		String name = vo.get("name");
		String value = vo.get("value");
		StudentDO student = studentService.getStudentById(studentId);
		boolean valid = StudentControllerHelper.setAttribute(student, name, value);
		if (valid) {
			studentService.updateStudent(student);
			return ControllerHelper.successResponse(null);
		} else {
			return ControllerHelper.errorResponse(1, "invalid parameter");
		}
	}

	@PostMapping("/{id}/bank-accounts")
	@ResponseBody
	public Map<String, Object> addBankAccount(@PathVariable("id") Integer studentId, @RequestBody StudentVO vo) {
		StudentBankAccountDO bankAccount = vo.toBankAccountDO();
		bankAccount.setStudentId(studentId);
		studentService.insertBankAccount(bankAccount);
		return ControllerHelper.successResponse(null);
	}

	@PostMapping("/{id}/bank-accounts/{bankAccountId}")
	@ResponseBody
	public Map<String, Object> updateBankAccount(@PathVariable("id") Integer studentId,
			@PathVariable("bankAccountId") Integer bankAccountId, @RequestBody StudentVO vo) {
		StudentBankAccountDO bankAccount = vo.toBankAccountDO();
		bankAccount.setStudentId(studentId);
		bankAccount.setId(bankAccountId);
		studentService.updateBankAccount(bankAccount);
		return ControllerHelper.successResponse(null);
	}
	
	@GetMapping("/exportPDF/{id}")
	@ResponseBody 
	public Map<String, Object> exportPDF(@PathVariable("id") Integer studentId, HttpServletRequest request, HttpServletResponse response) {
		System.out.print(studentId); 
		String fileName = studentService.exportStudentPDF(studentId);
		response.reset();
	    response.setContentType("application/pdf");
	    response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");

	    byte[] b = new byte[100];
	    int len =0;
	    try {
	      FileInputStream inStream =new FileInputStream(fileName);
	      while ((len = inStream.read(b)) > 0) {
	        response.getOutputStream().write(b, 0, len);
	      }
	      File file =new File(fileName); // 删除临时文件
	      // 如果文件存在 删除。
	      if(file.exists()){
	        file.delete();
	      }
	      inStream.close();
	    } catch (IOException e) {
	      e.printStackTrace();
	    }
	    System.out.println(fileName);
		return ControllerHelper.successResponse(fileName);
	}

}
